using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel.Channels;
using Microsoft.Samples.SsbTransportChannel;

namespace SsbTransportTestSuite
{

    class Program
    {
        private class BindingPair
        {
            public BindingPair(string Name, Binding ClientBinding, Binding ServiceBinding)
            {
                this.Name = Name;
                this.ServiceBinding = ServiceBinding;
                this.ClientBinding = ClientBinding;
            }
            public string Name;
            public Binding ClientBinding;
            public Binding ServiceBinding;
        }

        delegate int RunTestDelegate(Binding serviceBinding, Binding clientBinding);
        static Dictionary<string, RunTestDelegate> tests = BuildTestDelegates();
        static Dictionary<string, RunTestDelegate> BuildTestDelegates()
        {
            Dictionary<string, RunTestDelegate> td = new Dictionary<string, RunTestDelegate>();
            td.Add("oneway",new RunTestDelegate(TestSuite.DoOneWayTest));
            td.Add("twoway",new RunTestDelegate(TestSuite.DoTwoWayTest));
            td.Add("enlistment", new RunTestDelegate(TestSuite.DoEnlistingTest));
            td.Add("persistent",new RunTestDelegate(TestSuite.DoPersistentTest));

            return td;
        }


        static int Main(string[] args)
        {

            Arguments commandline = new Arguments(args);
            string test=commandline["test"];
            if (String.IsNullOrEmpty(test))
            {
                return ErrorReporter.ReportError("Arguments missing the test argument. Use /test to specify the test name");
            }


            IEnumerable<BindingPair> testBindings = ConfigureTestBindings();


            

            if (test == "all")
            {
                foreach (string testName in tests.Keys)
                {
                    Console.WriteLine("-------------------------------");
                    Console.WriteLine("-------------------------------");
                    Console.WriteLine("Running Test {0}", testName);
                    Console.WriteLine("-------------------------------");
                    int rc = RunTest(testName, testBindings);
                    if (rc != 0)
                        return rc;
                }
                return 0;
            }
            else
            {
                return RunTest(test,testBindings);
            }
        }

        private static IEnumerable<BindingPair>  ConfigureTestBindings()
        {
            List<BindingPair> testBindings = new List<BindingPair>();
            {
                SsbBinding clientBinding = new SsbBinding();
                clientBinding.SqlConnectionString = TestUtils.GetConnectionString("clientBinding");
                
                SsbBinding serviceBinding = new SsbBinding();
                serviceBinding.SqlConnectionString = TestUtils.GetConnectionString("serviceBinding");

                testBindings.Add(new BindingPair("Default",clientBinding, serviceBinding));
            }
            {
                SsbBinding clientBinding = new SsbBinding();
                clientBinding.SqlConnectionString = TestUtils.GetConnectionString("clientBinding");
                clientBinding.UseEncryption = true;
                clientBinding.UseActionForSsbMessageType = false;
                clientBinding.Contract = "DEFAULT";

                SsbBinding serviceBinding = new SsbBinding();
                serviceBinding.SqlConnectionString = TestUtils.GetConnectionString("serviceBinding");
                serviceBinding.UseEncryption = true;
                serviceBinding.UseActionForSsbMessageType = false;
                serviceBinding.Contract = "DEFAULT";
                testBindings.Add(new BindingPair("Encrypted",clientBinding, serviceBinding));
            }
            {
                SsbBinding clientBinding = new SsbBinding();
                clientBinding.SqlConnectionString = TestUtils.GetConnectionString("clientBinding");
                clientBinding.UseEncryption = false;
                clientBinding.UseActionForSsbMessageType = true;
                clientBinding.Contract = "http://ssbtransport/tests/OrderServiceContract";

                SsbBinding serviceBinding = new SsbBinding();
                serviceBinding.SqlConnectionString = TestUtils.GetConnectionString("serviceBinding");
                serviceBinding.UseEncryption = false;
                serviceBinding.UseActionForSsbMessageType = true;
                serviceBinding.Contract = "http://ssbtransport/tests/OrderServiceContract";
                testBindings.Add(new BindingPair("Contract", clientBinding, serviceBinding));
            }
            return testBindings;
        }
        static int RunTest(string test, IEnumerable<BindingPair> bindings)
        {
            if (!tests.ContainsKey(test))
            {
                return ErrorReporter.ReportError("Unknwon test name " + test);
            }

            int ec = 0;
           foreach (BindingPair bp in bindings)
           {
               Console.WriteLine("Running test {0}, with binding {1}",test,bp.Name);
               TestUtils.ResetQueues();
               int rc = tests[test].Invoke(bp.ClientBinding, bp.ServiceBinding);
               TestUtils.ValidatePostTestQueueState();
               if (rc != 0)
               {
                   ec = rc;
                   ErrorReporter.ReportError("Test Failed");
               }
                 
           }
           return ec;
        }

     

    }
}
